﻿

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEngine;

public class WrlHelper
{
    string wrlFileInfo;
    public List<WrlEntity> wrls = new List<WrlEntity>();
    public WrlEntity currentWrl = new WrlEntity();
    public int level = 0;
    public List<WrlEntity> ReadWrl(string path, ref string msg)
    {
        if (!File.Exists(path))
        {
            msg = "文件不存在";
            return null;
        }
        wrlFileInfo = File.ReadAllText(path);
        if (!wrlFileInfo.Contains("VRML V2.0"))
        {
            msg = "wrl文件不是v2.0版本";
            return null;
        }
        MatchCollection mc;
        int[] matchposition = new int[2000];
        Regex r = new Regex(@"Transform"); //定义一个Regex对象实例
        mc = r.Matches(wrlFileInfo);
        for (int i = 0; i < mc.Count; i++) //在输入字符串中找到所有匹配
        {
            matchposition[i] = mc[i].Index; //记录匹配字符的位置
                                            // Debug.Log(i + ":" + mc[i].Index);
            if (i == 0)
            {
                currentWrl = new WrlEntity();
                if (mc.Count == 1)
                {
                    int left = GetCount(@"\[", wrlFileInfo.Substring(0, wrlFileInfo.Length));
                    int right = GetCount(@"\]", wrlFileInfo.Substring(0, wrlFileInfo.Length));
                    GetTransform(wrlFileInfo.Substring(mc[i].Index, wrlFileInfo.Length - mc[i].Index), currentWrl);
                    currentWrl.shapeInfo = GetShape(wrlFileInfo.Substring(mc[i].Index, wrlFileInfo.Length - mc[i].Index), left, right);
                    BreakUpShape(currentWrl.shapeInfo, currentWrl);

                }
                else
                {
                    int left = GetCount(@"\[", wrlFileInfo.Substring(0, mc[i + 1].Index));
                    int right = GetCount(@"\]", wrlFileInfo.Substring(0, mc[i + 1].Index));
                    GetTransform(wrlFileInfo.Substring(mc[i].Index, mc[i + 1].Index - mc[i].Index), currentWrl);
                    currentWrl.shapeInfo = GetShape(wrlFileInfo.Substring(mc[i].Index, mc[i + 1].Index - mc[i].Index), left, right);
                    BreakUpShape(currentWrl.shapeInfo, currentWrl);
                }
                currentWrl.name = "model" + System.Guid.NewGuid().ToString();
                wrls.Add(currentWrl);
            }
            else
            {
                int left = GetCount(@"\[", wrlFileInfo.Substring(0, mc[i].Index));
                int right = GetCount(@"\]", wrlFileInfo.Substring(0, mc[i].Index));
                WrlEntity w = new WrlEntity();
                w.name = "model" + System.Guid.NewGuid().ToString();
                if (i >= mc.Count - 1)
                {
                    // left = GetCount(@"\[", wrlFileInfo.Substring(0, wrlFileInfo.Length));
                    // right = GetCount(@"\]", wrlFileInfo.Substring(0, wrlFileInfo.Length));
                    GetTransform(wrlFileInfo.Substring(mc[i].Index, wrlFileInfo.Length - mc[i].Index), w);
                    w.shapeInfo = GetShape(wrlFileInfo.Substring(mc[i].Index, wrlFileInfo.Length - mc[i].Index), left, right);
                    BreakUpShape(w.shapeInfo, w);
                    //   Debug.Log(left+","+right);
                }
                else
                {
                    GetTransform(wrlFileInfo.Substring(mc[i].Index, mc[i + 1].Index - mc[i].Index), w);
                    w.shapeInfo = GetShape(wrlFileInfo.Substring(mc[i].Index, mc[i + 1].Index - mc[i].Index), left, right);
                    BreakUpShape(w.shapeInfo, w);
                }

                if ((left - right) > level)//深入一级父子关系，新模型为当前模型（前一次解析的）的子物体
                {

                    w.parentEntity = currentWrl;
                    currentWrl.childs.Add(w);
                    currentWrl = w;

                }
                else if ((left - right) == level)//平级，新模型为当前模型（前一次解析的）的同级兄弟
                {
                    if (currentWrl.parentEntity == null)
                    {
                        wrls.Add(w);
                    }
                    else
                    {
                        w.parentEntity = currentWrl.parentEntity;
                        currentWrl.parentEntity.childs.Add(w);
                    }
                    currentWrl = w;

                }
                else if ((left - right) < level)//往上若干级，新模型为当前模型（往上ruu）的同级兄弟
                {

                    for (int j = (left - right); j < level; j++)
                    {
                        currentWrl = currentWrl.parentEntity;
                    }
                    w.parentEntity = currentWrl.parentEntity;
                    if (currentWrl.parentEntity == null)
                    {
                        wrls.Add(w);
                    }
                    else
                    {
                        currentWrl.parentEntity.childs.Add(w);
                    }
                    currentWrl = w;

                }
                level = left - right;
            }
        }
        return wrls;
    }
    #region 提取Transform
    public void GetTransform(string info, WrlEntity wrlEntity)
    {
        if (info.IndexOf("translation") == -1)
            return;
        string transformInfo = info.Substring(info.IndexOf("translation"), info.IndexOf("children") - info.IndexOf("translation"));
        string[] strs = transformInfo.Split('\n');
        int i = 0;
        foreach (string str in strs)
        {
            if (str.Contains("translation"))
            {
                string translationInfo = str.Trim(' ');
                string[] childs = translationInfo.Split(' ');
                if (childs.Length == 4)
                {
                    wrlEntity.translation = new Vector3(float.Parse(childs[1]),
                                                        float.Parse(childs[2]),
                                                        float.Parse(childs[3]));
                }
            }
            else if (str.Contains("rotation"))
            {
                string rotationInfo = str.Trim(' ');
                string[] childs = rotationInfo.Split(' ');
              
                if (childs.Length == 5)
                {
                    float x = float.Parse(childs[1]),  y = float.Parse(childs[2]), z = float.Parse(childs[3]), angle = float.Parse(childs[4])*0.5f;
                    float rotX = Mathf.Sin(angle) * x, rotY = Mathf.Sin(angle) * y, rotZ = Mathf.Sin(angle) * z, rotW = Mathf.Cos(angle);
                    wrlEntity.rotation = new Quaternion(rotX,rotY,rotZ,rotW).eulerAngles;  
                }
            }
            else if (str.Contains("scale"))
            {
                string scaleInfo = str.Trim(' ');
                string[] childs = scaleInfo.Split(' ');
                if (childs.Length == 4)
                {
                    wrlEntity.scale = new Vector3(float.Parse(childs[1]),
                                                        float.Parse(childs[2]),
                                                        float.Parse(childs[3]));
                }
            }
            i++;
        }
        // Debug.Log(transformInfo);
    }
    #endregion
    #region 提取shape
    private string GetShape(string info, int left, int right)
    {
        string shapeInfo = "";
        if (left > right)
        {
            int startIndex = info.IndexOf('[');
            shapeInfo = info.Substring(startIndex + 1, info.Length - startIndex - 1);
        }
        else if (left == right)
        {
            int startIndex = info.IndexOf('[');
            int endIndex = info.LastIndexOf(']');
            shapeInfo = info.Substring(startIndex + 1, endIndex - startIndex - 1);
        }
        else
        {
            int startIndex = info.IndexOf('[');
            int endIndex = info.LastIndexOf(']');
            for (int i = 0; i < (right - left); i++)
            {
                endIndex = info.LastIndexOf(']');
                info = info.Substring(0, endIndex);
            }
            endIndex = info.LastIndexOf(']');
            shapeInfo = info.Substring(startIndex + 1, endIndex - startIndex - 1);
        }
        shapeInfo = shapeInfo.Substring(0, shapeInfo.LastIndexOf('}') + 1);
        shapeInfo = shapeInfo.Trim();
        return shapeInfo;
    }
    #endregion
    #region 统计字符出现次数
    public int GetCount(string target, string str)
    {
        MatchCollection mc;
        int[] matchposition = new int[2000];
        Regex r = new Regex(target); //定义一个Regex对象实例
        mc = r.Matches(str);
        int left = mc.Count;
        return left;
    }
    #endregion

    /// <summary>
    /// 将shape文本的内容进一步分割
    /// </summary>
    /// <param name="shapeInfo">shape文本</param>
    /// <param name="wrlEntity">wrl对象</param>
    public void BreakUpShape(string shapeInfo,WrlEntity wrlEntity)  
    {
        shapeInfo = shapeInfo.Replace("\t", string.Empty).Replace("{", string.Empty);
        if(shapeInfo!=""&&shapeInfo!=null)
        {
            try
            {
                int startIndex = shapeInfo.IndexOf("material");
                int endIndex = shapeInfo.IndexOf("geometry");
                string materialInfo = "";
                materialInfo=shapeInfo.Substring(startIndex, endIndex - startIndex);
                var matInfoApart = materialInfo.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                string diffuseColorInfo = "";
                for (int i = 0; i < matInfoApart.Length; i++)
                    if (matInfoApart[i].Contains("diffuseColor"))
                    {
                        diffuseColorInfo = matInfoApart[i];
                        break;
                    }
                shapeInfo = shapeInfo.Replace("\r\n", string.Empty);

                startIndex = shapeInfo.IndexOf("geometry");
                string geometryInfo = "";
                geometryInfo= shapeInfo.Substring(startIndex, shapeInfo.Length - startIndex);
                var geoInfoApart = geometryInfo.Split("}".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                string vertexsInfo = "", trianglesInfo = "";
                for (int i = 0; i < geoInfoApart.Length; i++)
                {
                    if (geoInfoApart[i].Contains("Coordinate"))
                    {
                        startIndex = geoInfoApart[i].IndexOf("point");
                        endIndex = geoInfoApart[i].IndexOf("]");
                        vertexsInfo = geoInfoApart[i].Substring(startIndex, endIndex - startIndex);
                        vertexsInfo = vertexsInfo.Replace("[", string.Empty);
                    }
                    if (geoInfoApart[i].Contains("coordIndex"))
                    {
                        startIndex = geoInfoApart[i].IndexOf("coordIndex");
                        endIndex = geoInfoApart[i].IndexOf("]");
                        trianglesInfo = geoInfoApart[i].Substring(startIndex, endIndex - startIndex);
                        trianglesInfo = trianglesInfo.Replace("[", string.Empty);
                    }
                }
                wrlEntity.diffuseColorInfo = diffuseColorInfo;
                wrlEntity.vertexsInfo = vertexsInfo;
                wrlEntity.trianglesInfo = trianglesInfo;
            }
            catch (Exception) { Debug.Log("shape分割出错"); }
        }
        else
        {
            Debug.Log("当前shape内容为空");
        }
      
    } 
}
